package org.az.netty_study.p02_nio组件之channel;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * jdk7引入了Path和Paths类
 * 1.Path:表示文件或文件夹路径
 * 2.Paths:工具类，获取Path实例
 */
@Slf4j
public class _3_Path和Files {
    public static void main(String[] args) throws IOException {
        /**
         * Path path = Paths.get("123.txt"); 相对路径
         * Path path = Paths.get("E:\\123.txt"); 绝对路径
         * Path path = Paths.get("E:\\a", "b", "c"); 表示路径E:\\a\\b\\c
         * . 表示当前路径
         * .. 表示上一级路径
         * E:\\a\\b\\c\\..\\d -> E:\\a\\b\\d
         */
        Path path = Paths.get("123.txt");

        /**
         * Files.exists(Path):判断文件或文件夹是否存在
         * Files.createDirectories(Path):根据path来创建文件夹(存在则抛异常),只能创建一级目录
         * Files.createDirectories(Path):根据path来创建文件夹(存在则抛异常),可以创建多级目录
         * Files.copy(Path1, Path2, ?StandardCopyOption):拷贝文件, 参数：被拷贝文件from，拷到哪去to，?拷贝选项(StandardCopyOption.REPLACE_EXISTING表示to文件如果存在则覆盖)
         * Files.move(Path1, Path2, ?StandardCopyOption):移动文件，参数跟copy一样
         * Files.delete(path):删除文件或文件夹(如果目录有内容，则会抛异常)
         * Files.walkFileTree(Path， FileVisitor):遍历目录，参数：Path(从哪开始遍历)， FileVisitor(遍历到文件或文件夹时的回调函数)
         */
        System.out.println(Files.exists(path));
        System.out.println(Files.createDirectory(path));
        Files.copy(Paths.get("src\\main\\resources\\from.txt"), Paths.get("src\\main\\resources\\to1.txt"), StandardCopyOption.REPLACE_EXISTING);
        Files.delete(path);
        Files.delete(Paths.get("src\\main\\resources\\to1.txt"));

        //遍历文件夹
        m1(System.getProperty("java.home"));
        //文件夹对拷
        m2("src\\main\\resources\\path1", "src\\main\\resources\\path2");
        //删除多级目录
        m3("src\\main\\resources\\path2");
    }

    private static void m2(String from, String to) throws IOException {
        Files.walkFileTree(Paths.get(from), new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                Path toDir = Paths.get(dir.toString().replace(from, to));
                if (Files.notExists(toDir)) {
                    //遍历到文件夹，新建文件夹
                    Path newDir = Files.createDirectories(toDir);
                    log.info("创建新文件夹 -> " + newDir);
                }
                return super.preVisitDirectory(dir, attrs);
            }

            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                Path toFile = Paths.get(file.toString().replace(from, to));
                if (Files.notExists(toFile)) {
                    //遍历到文件，copy文件
                    Path newFile = Files.copy(file, toFile);
                    log.info("创建新文件 -> " + newFile);
                }
                return super.visitFile(file, attrs);
            }
        });
    }

    private static void m3(String dir) throws IOException {
        Files.walkFileTree(Paths.get(dir), new SimpleFileVisitor<Path>() {
            //是文件，直接删除
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                Files.delete(file);
                log.info("===>删除文件" + file);
                return super.visitFile(file, attrs);
            }
            //退出文件夹时，里面的文件(文件夹)肯定删完了
            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                Files.delete(dir);
                log.info("删除文件夹" + dir);
                return super.postVisitDirectory(dir, exc);
            }
        });
    }

    private static void m1(String dir) throws IOException {
        AtomicInteger dirCount = new AtomicInteger();
        AtomicInteger fileCount = new AtomicInteger();
        Files.walkFileTree(Paths.get(dir), new SimpleFileVisitor<Path>() {
            //进入文件夹之前的回调
            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                log.info("===>" + dir);
                dirCount.incrementAndGet();
                return super.preVisitDirectory(dir, attrs);
            }

            //遍历到文件时的回调
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                log.info(file.toString());
                fileCount.incrementAndGet();
                return super.visitFile(file, attrs);
            }
            //其他方法按需实现
        });
        System.out.println(dirCount.get());
        System.out.println(fileCount.get());
    }
}
